package Threads;

import java.net.Socket;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;

import Structs.Log;
import Structs.Member;
import Structs.Msg_broad;
import Structs.Msg_rsp;
import Structs.Task;
import Debug.Debug;
import Enums.Type_rsp;
import Interfaces.C_interface;

public class S_dispatcher implements Runnable{
	
	private Hashtable<String,Object> OnlineClients;
	private Hashtable<Integer,Task> Tasks;
	
	private BlockingQueue<Task> rmi_requests;
	private BlockingQueue<Msg_broad> Broadcast;
	private BlockingDeque<Log> log;
	Msg_rsp build_msg;
	
	
	
	public S_dispatcher(Hashtable<Integer,Task > Tasks ,
			BlockingQueue<Msg_broad> Broadcast,
			BlockingDeque<Log> log,
			Hashtable<String,Object> OnlineClients,
			BlockingQueue<Task> rmi_requests){
		
		this.Broadcast = Broadcast;
		this.log = log;
		this.Tasks = Tasks;
		this.OnlineClients = OnlineClients;
		
		this.rmi_requests = rmi_requests;
		
		new Thread(this).start();
		
	}

	public void run() {
		Msg_broad temp;
		Enumeration<Object> obj_enum;
		Object temp_obj;
		Task tmp;
		
		while (true){
			
			try {
				
				tmp=rmi_requests.take();
				
				System.out.println("New request Found");
				
				try{
					
					if(Tasks.containsKey(tmp.getId())){
					
						if(tmp.getTitulo().equals("Finish")){
							
							System.out.println("Finish task");
							FinishTask(tmp.getId(),tmp.getAuthor());
							
						} 
						else {
							
							System.out.println("edit task");
							EditTask(tmp.getId(),tmp.getTitulo(),tmp.getModified(),tmp.getAuthor());
							
						}
						
					}else
						if(tmp.getTitulo().equals("List")){
							
							System.out.println("List task");
							ListTasks(tmp.getAuthor());
							
						} else{
							if(tmp.getId()==0){
								System.out.println("Create task");
								CreateTask(tmp.getTitulo(), tmp.getAuthor(), tmp.getModified());
							} else {
								System.out.println("Task doesnt exist");
								build_msg =  new Msg_rsp(Type_rsp.Error, "Invalid Task ", 0);
								
								Broadcast.add(new Msg_broad(Type_rsp.Error,null,build_msg,tmp.getAuthor()));
							}
						}
					
				}catch(NullPointerException e){
					if(new Debug().isDebug())
						System.out.println("");
				
				}
				
			} catch (InterruptedException e) {
				if(new Debug().isDebug())
					System.out.println("Interrupted in S_dispatcher");
			}
		}
	}
	
	public boolean CreateTask(String Title,Member User, GregorianCalendar Date) {
		
		Enumeration<Integer> id_e = Tasks.keys();
		Integer id=0;
		Msg_broad request;
		
		while(id_e.hasMoreElements()){
			id = id_e.nextElement();
		}
		
		id=id+1;
		Task t = new Task(Title,User,Date);
		Tasks.put(id, t);
		
		build_msg =  new Msg_rsp(Type_rsp.NewTask, "Task Created", id);		
		
		request = new Msg_broad(Type_rsp.NewTask,null,build_msg,User);
		
		Broadcast.add(request);
		
		return true;
	}

	public boolean FinishTask(Integer Id,Member User) {
		Msg_broad request;
		
		if(Tasks.containsKey(Id)){
		
			Tasks.get(Id).setComplete(true);
			
			build_msg =  new Msg_rsp(Type_rsp.FinishTask, "Task Finished", Id);		
			
			request = new Msg_broad(Type_rsp.FinishTask,null,build_msg,User);
			
			Broadcast.add(request);
			
			return true;
			
		}else {
			build_msg =  new Msg_rsp(Type_rsp.Error, "Not finished or invalid Task ", 0);
			
			request = new Msg_broad(Type_rsp.Error,null,build_msg,User);
			
			Broadcast.add(request);
		}
		
		System.out.println("Task does not exist");
		
		return false;
	}

	public boolean EditTask(int Id,String titulo, GregorianCalendar modified,Member User) {
		
		Msg_broad request;
		
		if(Tasks.containsKey(Id)){
	
			Tasks.get(Id).setModified(modified);
			Tasks.get(Id).setTitulo(titulo);

			build_msg =  new Msg_rsp(Type_rsp.EditTask, "Task edited", Id);
			
			request = new Msg_broad(Type_rsp.EditTask,null,build_msg,User);
			
			Broadcast.add(request);
			
			return true;
		} else {
			build_msg =  new Msg_rsp(Type_rsp.Error, "Not edited or invalid Task ", 0);
			
			request = new Msg_broad(Type_rsp.Error,null,build_msg,User);
		}
		
		System.out.println("Task does not exist");
		
		return false;
	
	}
	
	public String ListTasks(Member User){
		String message = "";
		Enumeration<Integer> id_e = Tasks.keys();
		Integer id;
		Msg_broad request;
		
		while(id_e.hasMoreElements()){
			
			id = id_e.nextElement();
			message = message+Tasks.get(id).toMessageString(id)+"\n";
	
		};
	
		build_msg = new Msg_rsp(Type_rsp.ListTasks, message, 0);;
		
		request = new Msg_broad(Type_rsp.ListTasks,null,build_msg,User);
		
		Broadcast.add(request);
		
		return message;
	}
}
